import java.io.*;
import java.net.*;
import java.util.Scanner;

/**
 * This is the client. It is used to communicate with the server. After login
 * has been completed and language updated, the menu operation is directed from
 * the server.
 * 
 * @author Elite Bank
 */
public class ATMClient {
	private static int			connectionPort	= 8989;
	Socket						socket			= null;
	private DataOutputStream	out				= null;
	private DataInputStream		in				= null;
	private String				languageData	= "";
	private String[]			messages;

	/**
	 * Sends the account number for server verification.
	 */
	private boolean sendAccountNumber(int accountNumber) throws IOException,
			ClassNotFoundException {
		(new ATMPacket(ATMPacket.INT_ACCOUNT_NUMBER, accountNumber)).writeOut(out);
		ATMPacket p = ATMPacket.readIn(in);
		return (p.getPacketType() == ATMPacket.CMD_OK);
	}

	/**
	 * Sends the account passcode for server verification.
	 */
	private boolean sendAccountPasscode(int accountNumber) throws IOException,
			ClassNotFoundException {
		(new ATMPacket(ATMPacket.INT_PASS_CODE, accountNumber)).writeOut(out);
		ATMPacket p = ATMPacket.readIn(in);
		return (p.getPacketType() == ATMPacket.CMD_OK);
	}

	/**
	 * constructor and main loop.
	 * 
	 * @param adress
	 *            the IP-adress of the server.
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public ATMClient(String adress) throws IOException, ClassNotFoundException {
		try {
			socket = new Socket(adress, connectionPort);
			out = new DataOutputStream(socket.getOutputStream());
			in = new DataInputStream(socket.getInputStream());
		} catch (UnknownHostException e) {
			System.err.println("Unknown host: " + adress);
			System.exit(1);
		} catch (IOException e) {
			System.err.println("Couldn't open connection to " + adress);
			System.exit(1);
		}

		// Read stored language
		languageData = readTextFile("languageData.txt");
		messages = languageData.split("<newpost>");

		Scanner scanner = new Scanner(System.in);

		// Send accountnumber
		System.out.println("Enter accountnumber:");
		System.out.print("> ");
		while (!scanner.hasNextInt()) {
			scanner.next();
		}
		int accountNumber = scanner.nextInt();

		if (sendAccountNumber(accountNumber))
			System.out.println("Account number accepted!");
		else
			System.err.println("Account number error!");

		// Send password
		boolean passOk = false;
		while (!passOk) {
			System.out.println("Enter passcode:");
			System.out.print("> ");
			while (!scanner.hasNextInt()) {
				scanner.next();
			}
			int accountPasscode = scanner.nextInt();

			if (sendAccountPasscode(accountPasscode)) {
				System.out.println("Password accepted!");
				passOk = true;
			} else
				System.err.println("Password error!");
		}

		ATMPacket p;
		// MENU LOOP, controlled by the server.
		scanner = new Scanner(System.in);
		boolean doRun = true;
		while (doRun) {
			p = (ATMPacket.readIn(in));
			int pt = p.getPacketType();
			switch (pt) {
				case (ATMPacket.INT_DISP_SWITCH):
					int msgNum = p.getIntData();
					if (msgNum >= 0 && msgNum < messages.length)
						System.out.print(messages[p.getIntData()]);
					else
						System.err.println("Language error! ID= " + msgNum);
					break;
				case (ATMPacket.INT_DISP_NUMBER):
					System.out.print(p.getIntData() + "\n");
					break;
				case (ATMPacket.REQUEST_INT):
					System.out.print("> ");
					try {
						while (!scanner.hasNextInt()) {
							scanner.next();
							System.out.print("> ");
						}
						(new ATMPacket(ATMPacket.INT_CONTAINER, scanner.nextInt())).writeOut(out);
					} catch (Exception e) {
						e.printStackTrace();
					}
					break;
				case (ATMPacket.REQUEST_LANG):
					(new ATMPacket(ATMPacket.INT_CONTAINER, languageData.hashCode())).writeOut(out);
					break;
				case (ATMPacket.STR_NEW_LANG):
					languageUpdate(p.getStrData());
					break;
				case (ATMPacket.STR_CONTAINER):
					System.out.println(p.getStrData());
					break;
				case (ATMPacket.REQUEST_SHUTDOWN):
					doRun = false;
					break;
			}
		}
		scanner.close();
		socket.close();
	}

	/**
	 * language update
	 * 
	 * @throws IOException
	 *             Language update unsuccessful
	 * @throws ClassNotFoundException
	 *             Language update unsuccessful
	 */
	private void languageUpdate(String languageData) throws IOException,
			ClassNotFoundException {
		BufferedWriter fileOut = new BufferedWriter(new FileWriter("languageData.txt"));
		fileOut.write(languageData);
		fileOut.close();
		this.languageData = languageData;
		messages = languageData.split("<newpost>");
		System.out.println("Language: " + messages[0]);

	}

	/**
	 * main method
	 * 
	 * @param args
	 *            The ip adress of server
	 * @throws IOException
	 * @throws ClassNotFoundException
	 */
	public static void main(String[] args) throws IOException,
			ClassNotFoundException {
		try {
			new ATMClient(args[0]);
		} catch (ArrayIndexOutOfBoundsException e) {
			System.err.println("Missing argument ip-adress");
			System.exit(1);
		}

	}

	private static String readTextFile(String filePath) {
		return (new Scanner(filePath)).useDelimiter("\\Z").next();
	}

}
